package graph

import "fmt"

/**
邻接表表示法
*/
type ATNode struct {
	pNext *ATNode //下一个节点指针
	value string  //节点值
	place int     //节点下标
}

func NewATNode(value string, place int) *ATNode {
	return &ATNode{
		value: value,
		place: place,
	}
}

type ATGraph struct {
	atList []*ATNode //邻接表数组
	vexNum int       //定点个数
	arcNum int       //边个数
}

/**
构造函数
参数说明：
vexNum: 顶点信息, key:顶点位置，value：顶点值
arcNum: 边信息，key：顶点位置，value：相交边信息
*/
func NewATGraph(vexInfo map[int]string, arcInfo map[int][]int) *ATGraph {
	vexNum := len(vexInfo)
	arcNum := len(arcInfo)
	atGraph := &ATGraph{
		atList: make([]*ATNode, vexNum),
		vexNum: vexNum,
		arcNum: arcNum,
	}

	//邻接表的初始化
	for index, atNode := range atGraph.atList {
		//数组初始化赋值
		value, _ := vexInfo[index]
		atNode = NewATNode(value, index)

		//节点链表赋值
		arcList, ok := arcInfo[index]
		if ok && len(arcList) > 0 {
			pNow := atNode
			for _, nodePlace := range arcList {
				node := NewATNode("", nodePlace)
				pNow.pNext = node
				pNow = pNow.pNext
			}
		}

		//节点下标赋值
		atNode.place = index

		atGraph.atList[index] = atNode
	}

	return atGraph
}

func (graph *ATGraph) Print() {
	for _, atNode := range graph.atList {
		str := atNode.value
		for pNow := atNode.pNext; pNow != nil; pNow = pNow.pNext {
			str += fmt.Sprintf(" %d ", pNow.place)
		}
		fmt.Printf("index: %d, value: %s, atNode: %s\n", atNode.place, atNode.value, str)
	}
}
